# *-* coding: utf-8 *-*

import sys
import serial
import threading
import re
import pygame
import math
import time
import numpy as np
from scipy.interpolate import griddata
from colour import Color

DEV_NAME = "COM52"
STR_UART_READ = ""
TEMP = ""
COLORDEPTH = 1024
height = 480
width = 480
displayPixelHeight = height / 30
displayPixelWidth = width / 30
points = [(math.floor(ix / 8), (ix % 8)) for ix in range(0, 64)]
grid_x, grid_y = np.mgrid[0:7:32j, 0:7:32j]
global lcd

print("")       # new line

def pygame_init():
    global lcd
    pygame.init()
    lcd = pygame.display.set_mode((width, height))
    lcd.fill((255, 0, 0))
    pygame.display.update()
    pygame.mouse.set_visible(False)
    lcd.fill((0, 0, 0))
    pygame.display.update()

blue = Color("indigo")
colors = list(blue.range_to(Color("red"), COLORDEPTH))
colors = [(int(c.red * 255), int(c.green * 255), int(c.blue * 255)) for c in colors]

def constrain(val, min_val, max_val):
    return min(max_val, max(min_val, val))

def map_value(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

if __name__ == "__main__":
    #print(sys.argv)
    if len(sys.argv) == 2:
        DEV_NAME = sys.argv[1]
    try:
        com = serial.Serial(DEV_NAME, 115200, timeout=None)
    except:
        print(DEV_NAME + " open failed.")
        exit()

    if(com.is_open == True):
        print(DEV_NAME + " open successful.")
        pygame_init()
        while True:
            try:
                STR_UART_READ = com.read().decode('utf-8')
            except:
                continue    # when receive the post-part of one character
            if STR_UART_READ == "[":
                TEMP = ""
                continue
            if STR_UART_READ == "]": 
                temp_array = []
                #print(TEMP)
                TEMP = re.sub(' ', '', TEMP)            # remove space
                TEMP = re.sub('\r\n', '', TEMP)         # remove \r\n
                TEMP = TEMP[:len(TEMP) - 1]             # remove last comma
                temp_array = TEMP.split(',')            # transfer string to array(split by comma)
                #print(temp_array)
                MINTEMP = min(temp_array)
                MAXTEMP = max(temp_array)

                try:
                    pixels = [map_value(float(p), float(MINTEMP), float(MAXTEMP), 0, COLORDEPTH - 1) for p in temp_array]
                    # perform interpolation
                    bicubic = griddata(points, pixels, (grid_x, grid_y), method="cubic")
                except:
                    continue    # when temp_array is NOT complete temp data

                print("MINTEMP: " + MINTEMP + "\tMAXTEMP: " + MAXTEMP, end="\r")

                # draw everything
                for ix, row in enumerate(bicubic):
                    for jx, pixel in enumerate(row):
                        pygame.draw.rect(lcd, colors[constrain(int(pixel), 0, COLORDEPTH - 1)],
                                         (
                                             displayPixelHeight * ix,
                                             displayPixelWidth * jx,
                                             displayPixelHeight,
                                             displayPixelWidth,
                                         ),
                                        )
                pygame.display.update()

                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        print("\nUART closed.")
                        com.close()
                        exit()

                #time.sleep(1)
            else:
                TEMP += STR_UART_READ
    
